home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-05 / lanutsrc.zip / MESSAGE.ASM < prev    next >
Assembly Source File  |  1991-03-13  |  11KB  |  420 lines

  1. INCLUDE \ASM\INCLUDE\BIOS.INC
  2. INCLUDE DEFS.INC
  3.  
  4. SAVELEN EQU    160            ; Number of words to save from scn.
  5. BIOS_SEG EQU    0040H
  6.  
  7. msv    SEGMENT
  8.     ASSUME  CS:msv
  9.     ASSUME  DS:msv
  10.     ASSUME  ES:msv
  11.     ASSUME  SS:NOTHING
  12.     ORG    0
  13. SEG_ORG    EQU    $    
  14.     ORG    100h
  15. main    PROC    FAR
  16. start:    jmp    init            ; Do initialization section
  17.  
  18. ;*******************************************************************
  19. ; LANOS VECTOR TSR portion of Message handler --
  20. ; The LANOS portion simply increments a message received flag and
  21. ; exits, leaving the actual processing of the message to an
  22. ; interrupt.
  23. ;*******************************************************************
  24. MSV_entry:    jmp first            ; skip data area
  25. ; LANOS MSR handler variables
  26. tsr_name    db    '■SM'
  27. color        db    70h
  28. msg_flag    db    0
  29. msg_time    dd    ?
  30. old_msr        dd    ?
  31.  
  32. ; Pop up Message Service variables
  33. from        db    'From: ',0      
  34. time        db    'Time: ',0        
  35. busy        db    0            ; TSR status flag
  36. c_pos        dw    ?        ; old cursor location
  37. old_vector2    dd    ?        ; address of previous kbd ISR
  38. buffer        message_buffer <>    ; local message buffer
  39. screen_data    dw    SAVELEN dup (?)    ; storage for old screen data     
  40. old_stk_seg    dw      ?               ; Calling program's stack info
  41. old_b_ptr    dw    ?
  42. old_stk_ptr    dw      ?
  43. new_stk_seg    dw      ?
  44. new_stk_ptr    dw    OFFSET TOS
  45.         dw    80 dup (?)    ; local stack data area
  46. TOS        equ    $        
  47.  
  48. ;************************************************************************
  49. ; Start of actual LANOS message handler
  50. ;************************************************************************
  51. first:  
  52. ; Save current clock count
  53.     cli                ; forbid additional interrupts
  54.     push    ax            ; save needed registers
  55.     push    ds        
  56.     push    si
  57.     
  58.      mov    ax,BIOS_SEG
  59.      mov    ds,ax            ; Point ds to BIOS data area
  60.      mov    si,006Ch        ; Offset of master clock dw.
  61.      
  62.      mov    ax,[si]            ; get the first word 
  63.      mov     word ptr cs:msg_time, ax
  64.      
  65.      inc    si                      ; get the second word
  66.      inc    si
  67.      mov    ax,[si]
  68.      mov    word ptr cs:msg_time + 2,ax
  69.      
  70.      pop    si
  71.      pop    ds
  72.      pop    ax
  73.  
  74.     inc    cs:msg_flag        ; set the message received flag
  75.  
  76. call_old_msr:
  77.     sti                ; allow interrupts
  78.     jmp    cs:old_msr
  79.  
  80. ;*****************************************************************************
  81. ; Interrupt E0 handler --- this is apparently something that LANtastic uses
  82. ; internally to indicate when DOS is safe.
  83. ;*****************************************************************************
  84. DOSFREE:
  85.     PUSHF
  86.     CALL CS:old_vector2                 ; give everyone else a chance...
  87.     
  88.     cmp  cs:msg_flag,0                  ; have our services been requested?
  89.     jz   Done_E0            ; If not, skip this stuff
  90.     CMP  CS:busy,0                      ; Are we already busy?
  91.     JNZ  Done_E0                        ; If so, skip this stuff
  92.  
  93. ; Activate the pop up routine
  94.     inc  cs:busy            ; set busy flag
  95.     call pop_up
  96.     mov  cs:msg_flag,0                ; reset received flag
  97.     dec     cs:busy                ; reset busy flag    
  98.  
  99. Done_E0:
  100.     IRET
  101.  
  102. ;***********************************************************************
  103. ; Pop-up message handler
  104. ; When we're popped up, an Esc keypress will take us back to normal
  105. ; processing
  106. ;***********************************************************************
  107. pop_up    PROC    near
  108.     @NewStack                  ; replace stack
  109.  
  110. ; Set all segment regs to CS for convenience
  111. set_seg:
  112.     push    cs            ; point all segregs to CS
  113.     push    cs
  114.     pop    ds
  115.     pop    es
  116.  
  117. ; Save the bottom line of the screen and highlight the message area
  118. save_cur:
  119.     mov    ah,03            ; get old cursor info
  120.     xor    bx,bx
  121.     int    10h            ; do it;
  122.     mov    cs:c_pos,dx        ; save old cursor location
  123.  
  124.     mov    di,OFFSET screen_data
  125.     mov    dx,1700h        ; point to line 23
  126.     mov    cx,2            ; number of lines to move
  127. save_row:
  128.     push    cx            ; save current row count
  129.     mov    cx,80            ; number of columns to move
  130. save_col:
  131.     call    CURSOR            ; move cursor to proper spot
  132.     push    cx            ; save char count
  133.     push    dx
  134.     @GetChAtr 0            ; get the current character
  135.     stosw                ; save current char/attr
  136.     @PutChAtr 32,color,0,1        ; highlight current char position
  137.     pop    dx
  138.     inc    dl            ; increment cursor position
  139.     pop    cx            ; restore char count
  140.     loop    save_col        ; go back for next char
  141.     
  142.     xor    dl,dl            ; set cursor to start of next row
  143.     inc    dh
  144.     pop    cx                      ; restore row count
  145.     loop    save_row        ; go back for next row
  146.  
  147. ; Get the address of the last unsolicited message
  148.     mov    di,OFFSET buffer
  149.     mov    ax,5F99H
  150.     int    21h    
  151.  
  152. ; Display the message text
  153.      mov    dx,1700h        ; point to line 23
  154.      call    CURSOR
  155.     mov    di,OFFSET buffer.MB_text
  156.            call    PRT_STR                 ; Display the message text
  157.  
  158.      mov    dx,1807h        ; row 24, column 7        
  159.      call    CURSOR
  160.     mov    di,OFFSET buffer.MB_originator
  161.      call    PRT_STR            ; Display sender's name
  162.  
  163. ; display text prompts
  164.     push    cs            ; point ES to current seg
  165.     pop    es
  166.      mov    dx,1800h                ; line 24, column 0
  167.      call    CURSOR
  168.      mov    di,OFFSET from        ; print from prompt
  169.      call    PRT_STR
  170.      
  171.      mov    dx,1818h        ;line 24, column 24
  172.      call    CURSOR
  173.      mov    di,OFFSET time        ; print time prompt
  174.      call    PRT_STR
  175.     
  176. ; Display the time
  177. ; load the clock count for use by DIV
  178.      mov    ax,word ptr msg_time
  179.      mov    dx,word ptr msg_time + 2
  180.  
  181.      push    ax        ; save count for easy access
  182.      push    dx
  183.  
  184. ; calculate number of minutes since midnight
  185.      mov    cx,1080
  186.      div    cx
  187.  
  188. ; calculate error in clock ticks
  189.      mov    cx,12
  190.      mul    cx
  191.      mov    bx,dx        ; save high word in bx
  192.      mov    cx,ax        ; save low word in cx
  193.  
  194. ; subtract the error from the original clock tick number
  195.      pop    dx        ; High order word
  196.      pop    ax        ; low order word
  197.  
  198.      sub    ax,cx        ; subtract low order word
  199.      sbb    dx,bx        ; subtract high order word
  200.  
  201. ; calculate the new, improved number of minutes since midnight
  202.      mov    cx,1080
  203.      div    cx
  204.  
  205. ; calculate hours since midnight
  206. ; leaves hours in AL and minutes in AH
  207.      mov    cl,60
  208.      div    cl
  209.  
  210.      push    ax            ; Save result
  211.      
  212.      mov    dx,181Eh        ; row 24, column 30
  213.      call    CURSOR
  214.      
  215.      mov    bl,al            ; Display hour
  216.      call    PRT_TIME
  217.      
  218.      mov    al,':'            ; display delimiter
  219.      call    PUT_CHAR
  220.      
  221.      pop    ax        
  222.      mov    bl,ah            ; Display minute
  223.      call     PRT_TIME
  224.  
  225. ; Wait for the user to press escape
  226. K_WAIT:
  227.     xor    ax,ax            ; Read keyboard char fn.
  228.     int    16h            
  229.  
  230.         cmp    al,27                   ; is it an escape?
  231.      jne     K_WAIT                  ; If not, try again
  232.         
  233. ; Restore the bottom line of the screen
  234. rest_cur:
  235.     mov    si,OFFSET screen_data
  236.     mov    dx,1700h        ; point to line 23
  237.     mov    cx,2            ; number of lines to move
  238. rest_row:
  239.     push    cx            ; save current row count
  240.     mov    cx,80            ; number of columns to move
  241. rest_col:
  242.     call    CURSOR            ; move cursor to proper spot
  243.     lodsw                ; get the word to save
  244.     push    cx            ; save char count
  245.     @PutChAtr    al,ah,0,1    ; write character/attribute
  246.     inc    dl            ; increment cursor position
  247.     pop    cx            ; restore char count
  248.     loop    rest_col        ; go back for next char
  249.     
  250.     xor    dl,dl            ; set cursor to start of next row
  251.     inc    dh
  252.     pop    cx                      ; restore row count
  253.     loop    rest_row        ; go back for next row
  254.  
  255.     mov    dx,c_pos        ; restore old cursor position
  256.     call    CURSOR
  257.  
  258. ; Restore calling program's stack setup
  259. BYPASS:    
  260.     @OldStack                       ; restore caller's stack
  261.         ret                ; return to caller
  262.  
  263. pop_up ENDP
  264.  
  265. ;*********************************************************************
  266. ; Subroutines
  267. ;********************************************************************
  268. ; Move cursor -- row in dh, col in dl
  269. CURSOR  PROC    NEAR
  270.     push    ax
  271.     push    bx
  272.     push    cx
  273.     
  274.     @SetCurPos    dl,dh,0 
  275.     
  276.         pop    cx
  277.         pop    bx
  278.         pop    ax
  279.         ret
  280. CURSOR  ENDP
  281.  
  282. PRT_STR    PROC    NEAR
  283. ;
  284. ; Write ASCIIZ string pointed to by ES:DI at current cursor position
  285. ;
  286. L3:
  287.     mov    al,es:[di]        ; get the character
  288.     or    al,al            ; See if it's a zero
  289.     jz    short L4        ; Yes- we're done
  290.     call    PUT_CHAR        ; display the character
  291.     inc    di            ; get the next char
  292.     jmp    short L3
  293. L4:
  294.     ret    
  295. PRT_STR    ENDP
  296.  
  297. ;
  298. ; Displays a number between 0 and 99 on the screen, at the location
  299. ; pointed to by es:di. Note that the number must be between 0 and 100.
  300. ; The number to be displayed must be in bx.
  301. ;
  302. PRT_TIME PROC NEAR
  303.     mov    ax,bx           ; extract the 10's digit    
  304.     xor    ah,ah           ; clear MSB so that we limit range    
  305.     mov    dl,10        
  306.     div    dl
  307.     mov    dx,ax           ; save result
  308.         
  309.     add    al,30H           ; convert quotient to ASCII
  310.     call    PUT_CHAR       ; print the digit    
  311.  
  312.         mov    al,dh           ; get remainder (1's digit)
  313.         add    al,30H         ; convert to ASCII
  314.         call    PUT_CHAR       ; print the digit    
  315.         ret
  316. PRT_TIME ENDP                
  317.  
  318. ;Print a character (the one in AL, hopefully) and advance the cursor
  319. PUT_CHAR PROC NEAR
  320.     push    dx
  321.     push    di
  322.  
  323.     mov    ah,0Eh        ; write char in tty mode
  324.     mov    bx,7        ; video page 0, gfx foreground 7
  325.     int    10h        ; display the character
  326.     
  327.     pop    di
  328.     pop    dx
  329.     ret
  330. PUT_CHAR ENDP    
  331. LAST_BYTE    EQU $
  332.  
  333. ;
  334. ;    Initialization -- thrown away after load
  335. ;
  336.  
  337. title1    db    "SoftMagic Resident Message Handler V1.61 for LANtastic",13,10,0
  338. title2    db    "Copyright 1989 by SoftMagic, Inc. All rights Reserved.",13,10,0
  339. title3    db    "     LANtastic is a trademark of Artisoft, Inc.",13,10,0
  340. title4    db     13,10,"The SoftMagic Resident Message Handler is already installed.",13,10,0
  341.  
  342. IFDEF    SHAREWARE
  343. title5  db      "Thanks for trying this unregistered Shareware edition.",7,13,10,0
  344. ENDIF
  345.  
  346. init:    mov    cs:busy,1           ; prevent activation
  347.     @NewStack            ; Set up local stack
  348.  
  349. ; Display title messge
  350.     mov     di,OFFSET title1
  351.     call    PRT_STR
  352.     mov    di,OFFSET title2
  353.     call    PRT_STR
  354.     mov    di,OFFSET title3
  355.     call     PRT_STR
  356.     
  357. IFDEF    SHAREWARE    
  358.     mov    di,OFFSET title5
  359.     call    PRT_STR
  360. ENDIF    
  361.  
  362. ; Get old LANOS message handler vector
  363.     mov     ax,5FE2h
  364.     int    21h
  365.     mov    word ptr old_msr,bx     ; Save the location of the old vector
  366.     mov    word ptr old_msr+2,es
  367.     
  368. ; See if our message handler is already loaded
  369.     mov    di,bx                
  370.     add    di,3                    ; Point to name area
  371.     cmp    byte ptr es:[di],254    ; Look for our signature byte
  372.     jnz     SHORT install           ; is it there?
  373.  
  374.     mov    ax,ds
  375.     mov    es,ax
  376.     mov    di,OFFSET title4
  377.     call    PRT_STR
  378.     mov    ah,4Ch            ; Terminate w/return function
  379.     int    21h            ; End the program
  380.  
  381. ;
  382. ; Replace the LANOS message service
  383. ;
  384.  
  385. install:
  386.     mov    ax,cs
  387.     mov    es,ax
  388.     mov    ax,5FE3h
  389.     mov    bx,OFFSET MSV_entry
  390.     int    21H
  391.  
  392. ;
  393. ; Replace LANtastic's internal DOS free vector
  394. ;
  395.     MOV  AX,5FE0H
  396.     INT  21H                            ; GET THE DOS FREE VECTOR
  397.     MOV  WORD PTR old_vector2,BX
  398.     MOV  WORD PTR old_vector2+2,ES
  399.  
  400. ;
  401. ; Set vector to our routine
  402. ;
  403.     push cs
  404.     pop  es    
  405.         MOV  BX,OFFSET DOSFREE
  406.         MOV  AX,5FE1H
  407.         INT  21H                           
  408.  
  409. ; Terminate and stay resident
  410.     @OldStack            ; Restore caller's stack
  411.     mov    cs:busy, 0              ; Enable pop-up
  412.     mov    dx,(offset LAST_BYTE - SEG_ORG + 15) shr 4
  413.     mov    ah,31h                  ; free memory and leave
  414.     int     21h
  415.  
  416. main    ENDP
  417. msv    ENDS
  418. END    start                        
  419.                     
  420.